﻿


using Prism.Regions;
using Prism.Services.Dialogs;
using System.Diagnostics;
using System;
using NLog;
using COVID_19_LiquidFillUI.Models;
using Newtonsoft.Json;
using System.IO;
using System.Windows.Forms;
using MessageBox = System.Windows.Forms.MessageBox;
using COVID_19_LiquidFillUI.Common.Services;
using Prism.Ioc;
using Prism.Events;
using COVID_19_LiquidFillUI.Common.Extensions;
using System.Threading.Tasks;

namespace COVID_19_LiquidFillUI.ViewModels
{
    public class MainWindowViewModel: BindableBase
    {
        #region 变量
        private readonly IDialogService dialogService;
        private readonly IRegionManager regionManager;
        public readonly IEventAggregator aggregator;
        bool isCameraCalcDialog1Show = false;
        private static Logger logger = LogManager.GetCurrentClassLogger();
        Param param;
        ICameraService cam0, cam1, cam2, cam3;
        IPLCModbusService plc;
        #endregion
        #region 属性绑定
        private string title;
        public string Title
        {
            get { return title; }
            set { SetProperty(ref title, value); }
        }
        private string version;
        public string Version
        {
            get { return version; }
            set { SetProperty(ref version, value); }
        }
        private bool pLCState;
        public bool PLCState
        {
            get { return pLCState; }
            set { SetProperty(ref pLCState, value); }
        }
        private bool camera0State;
        public bool Camera0State
        {
            get { return camera0State; }
            set { SetProperty(ref camera0State, value); }
        }
        private bool camera1State;
        public bool Camera1State
        {
            get { return camera1State; }
            set { SetProperty(ref camera1State, value); }
        }
        private bool camera2State;
        public bool Camera2State
        {
            get { return camera2State; }
            set { SetProperty(ref camera2State, value); }
        }
        private bool camera3State;
        public bool Camera3State
        {
            get { return camera3State; }
            set { SetProperty(ref camera3State, value); }
        }
        private string messageStr;
        public string MessageStr
        {
            get { return messageStr; }
            set { SetProperty(ref messageStr, value); }
        }
        #endregion
        #region 方法绑定
        private DelegateCommand appLoadedEventCommand;
        public DelegateCommand AppLoadedEventCommand =>
            appLoadedEventCommand ?? (appLoadedEventCommand = new DelegateCommand(ExecuteAppLoadedEventCommand));
        private DelegateCommand<object> menuCommand;
        public DelegateCommand<object> MenuCommand =>
            menuCommand ?? (menuCommand = new DelegateCommand<object>(ExecuteMenuCommand));
        private DelegateCommand appClosedEventCommand;
        public DelegateCommand AppClosedEventCommand =>
            appClosedEventCommand ?? (appClosedEventCommand = new DelegateCommand(ExecuteAppClosedEventCommand));

        void ExecuteAppClosedEventCommand()
        {
            aggregator.SendMessage("Closed", "App");
            cam1.CloseCamera();
            try
            {
                plc.WriteMCoils(701, new bool[3]);
                plc.WriteMCoils(711, new bool[3]);
            }
            catch { }
            plc.Close();

            logger.Info("软件关闭");
        }
        void ExecuteMenuCommand(object obj)
        {
            switch (obj.ToString())
            {
                case "camera0":
                    if (!isCameraCalcDialog1Show)
                    {
                        isCameraCalcDialog1Show = true;
                        DialogParameters param = new DialogParameters();
                        param.Add("CameraIndex", 0);
                        dialogService.Show("Station1CameraCalcDialog", param, arg =>
                        {
                            isCameraCalcDialog1Show = false;
                        });
                    }
                    break;
                case "camera1":
                    if (!isCameraCalcDialog1Show)
                    {
                        isCameraCalcDialog1Show = true;
                        DialogParameters param = new DialogParameters();
                        param.Add("CameraIndex", 1);
                        dialogService.Show("Station1CameraCalcDialog", param, arg =>
                        {
                            isCameraCalcDialog1Show = false;
                        });
                    }
                    break;
                case "camera2":
                    if (!isCameraCalcDialog1Show)
                    {
                        isCameraCalcDialog1Show = true;
                        DialogParameters param = new DialogParameters();
                        param.Add("CameraIndex", 2);
                        dialogService.Show("Station2CameraCalcDialog", param, arg =>
                        {
                            isCameraCalcDialog1Show = false;
                        });
                    }
                    break;
                case "camera3":
                    if (!isCameraCalcDialog1Show)
                    {
                        isCameraCalcDialog1Show = true;
                        DialogParameters param = new DialogParameters();
                        param.Add("CameraIndex", 3);
                        dialogService.Show("Station2CameraCalcDialog", param, arg =>
                        {
                            isCameraCalcDialog1Show = false;
                        });
                    }
                    break;
                default:
                    break;
            }
        }
        async void ExecuteAppLoadedEventCommand()
        {
            regionManager.Regions["CameraRegion0"].RequestNavigate("View1");
            regionManager.Regions["CameraRegion1"].RequestNavigate("View2");
            addMessage("软件开启");
            var r1 = await Task.Run(() => { return plc.Connect(param.PLCIP); });
            PLCState = r1;
            if (r1)
            {
                aggregator.SendMessage("PLCConnect", "App");
            }
            else
            {
                MessageBox.Show($"PLC:{param.PLCIP}连接失败", "确认", MessageBoxButtons.OK);
            }
        }
        #endregion
        #region 构造函数
        public MainWindowViewModel(IContainerProvider containerProvider, IRegionManager _regionManager, IDialogService _dialogService, IEventAggregator _aggregator)
        {
            Title = "COVID-19-LiquidFillUI";
            Version = "1.0.0";
            MessageStr = string.Empty;
            dialogService = _dialogService;
            regionManager = _regionManager;
            aggregator = _aggregator;
            NlogConfig();
            LoadParam();
            cam0 = containerProvider.Resolve<ICameraService>("Cam0");
            cam1 = containerProvider.Resolve<ICameraService>("Cam1");
            cam2 = containerProvider.Resolve<ICameraService>("Cam2");
            cam3 = containerProvider.Resolve<ICameraService>("Cam3");
            plc = containerProvider.Resolve<IPLCModbusService>("plc");
            aggregator.ResgiterMessage(arg => {
                switch (arg.Message)
                {
                    case "Camera0OpenOK":
                        Camera0State = true;
                        break;
                    case "Camera0OpenNG":
                        Camera0State = false;
                        break;
                    case "Camera1OpenOK":
                        Camera1State = true;
                        break;
                    case "Camera1OpenNG":
                        Camera1State = false;
                        break;
                    case "Camera2OpenOK":
                        Camera2State = true;
                        break;
                    case "Camera2OpenNG":
                        Camera2State = false;
                        break;
                    case "Camera3OpenOK":
                        Camera3State = true;
                        break;
                    case "Camera3OpenNG":
                        Camera3State = false;
                        break;
                    default:
                        break;
                }
            }, "Camera");
            aggregator.ResgiterMessage(arg => {
                addMessage(arg.Message);
            }, "Message");
        }
        #endregion
        #region 功能函数
        private void addMessage(string str)
        {
            logger.Info(str);
            Debug.WriteLine(str);
            string[] s = MessageStr.Split('\n');
            if (s.Length > 1000)
            {
                MessageStr = "";
            }
            if (MessageStr != "")
            {
                MessageStr += "\n";
            }
            MessageStr += DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " " + str;
        }
        private void NlogConfig()
        {
            var config = new NLog.Config.LoggingConfiguration();

            // Targets where to log to: File and Console
            var logfile = new NLog.Targets.FileTarget("logfile") { FileName = "${basedir}/logs/${shortdate}.log", Layout = "${longdate}|${level:uppercase=true}|${message}" };
            var logconsole = new NLog.Targets.ConsoleTarget("logconsole");

            // Rules for mapping loggers to targets            
            config.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, logconsole);
            config.AddRule(NLog.LogLevel.Debug, NLog.LogLevel.Fatal, logfile);

            // Apply config           
            NLog.LogManager.Configuration = config;
        }
        private void LoadParam()
        {
            try
            {
                //Json序列化，从文件读取
                string jsonString = File.ReadAllText(System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Param.json"));
                param = JsonConvert.DeserializeObject<Param>(jsonString);
            }
            catch (Exception ex)
            {
                logger.Error(ex);
                MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
        #endregion
    }
}
